<script lang="ts">
import {Vue, Component, Emit, Prop, Watch, Inject} from 'vue-property-decorator';
import {fieldProps} from "./InfoPreview";
import UnitSelect from "../Base/UnitSelect/UnitSelect.vue";
import LicenseSelect from "../Base/LicenseSelect/LicenseSelect.vue";
import BrandSelect from "../Base/BrandSelect/BrandSelect.vue";
import CommodityClass from "../Base/CommodityClass/CommodityClass.vue";
import ManageCategory from "../Base/ManageCategory/ManageCategory.vue"
import CommodityClassify from "../Base/CommodityClassify/CommodityClassify.vue"
import CommodityClassifyEdit from "../Base/CommodityClassifyEdit/CommodityClassifyEdit.vue"
import {LicenseEntity} from "../../plugins/dto";
import {BusinessType} from "../../type";
@Component({
  model: {
    prop: "value",
    event: "input"
  },
  components: {UnitSelect, LicenseSelect, BrandSelect, CommodityClass, ManageCategory, CommodityClassify, CommodityClassifyEdit},
})
export default class EditInput extends Vue {
  @Prop({default: ""})value!:string;
  @Prop({default:true})editable!:boolean;
  @Prop({default:{}})item!:fieldProps;
  @Prop({default: ""})render:string|undefined;
  @Inject('modeType') injectedModeType!: {mode: string};
  @Prop() handleSaveClick!: (val: any) => void;
  inner_value:string|LicenseEntity[] = "";
  init_value:string = "";  // 初始化value 或者 label
  init_origin_value:string|LicenseEntity[] = ""
  showEdit:boolean = false      // 是否展示修改按钮
  cursorFocus:boolean = false  // 光标是否聚焦
  disableMouseEnter:boolean = false;  // 进入事件失效
  inner_editable:boolean = false  // 内部编辑状态
  first_render:boolean = true;
  is_changed: boolean = false;
  is_showDiff: boolean = false;
  maxWidth:number = 240;
  labelValue:string= ""   // 修改后的label
  @Emit("input")
  handleInput(value: string|LicenseEntity[]) {
    return value
  }
  updated() {
    // this.setCaretToEnd()
  }

  mounted(){
    if (window.innerWidth < 1200){
      this.maxWidth = 110
    }else if(window.innerWidth > 1200 && window.innerWidth < 1440){
      this.maxWidth = 150
    }else if(window.innerWidth > 1440 && window.innerWidth < 1680){
      this.maxWidth = 180
    }else if(window.innerWidth > 1680 && window.innerWidth < 1920){
      this.maxWidth = 220
    }else if(window.innerWidth > 1920){
      this.maxWidth = 240
    }
    window.addEventListener("resize", ()=>{
      if (window.innerWidth < 1200){
        this.maxWidth = 110
      }else if(window.innerWidth > 1200 && window.innerWidth < 1440){
        this.maxWidth = 130
      }else if(window.innerWidth > 1440 && window.innerWidth < 1680){
        this.maxWidth = 200
      }else if(window.innerWidth > 1680 && window.innerWidth < 1920){
        this.maxWidth = 220
      }else if(window.innerWidth > 1920){
        this.maxWidth = 240
      }
    })
  }
  @Watch("item", {immediate: true, deep: true})
  itemChange(newValue:fieldProps, oldValue:fieldProps) {
    console.log("====>item", newValue, oldValue, this.first_render)
    if(!oldValue && newValue && this.first_render){
      this.init_value = newValue.value;
      this.init_origin_value = newValue.value
      this.inner_value = newValue.value
    }
    if(oldValue && oldValue.value !== newValue.value && this.first_render) {
      if(newValue && newValue.labelKey && this.first_render){
        if(newValue.multiple){
          //@ts-ignore
          this.init_value = newValue[newValue.key as keyof fieldProps].map((j)=>(j[newValue.labelKey])).join(",")
          //@ts-ignore
          this.inner_value = newValue[newValue.key as keyof fieldProps]
          //@ts-ignore
          this.init_origin_value = newValue[newValue.key as keyof fieldProps]
        }else{
          this.init_value = newValue[newValue.labelKey as keyof fieldProps];
          this.init_origin_value = newValue["value"];
          this.inner_value = newValue[newValue.labelKey as keyof fieldProps];
        }
      }else{
        this.init_value = newValue.value;
        this.init_origin_value = newValue.value
        this.inner_value = newValue.value
      }
      this.first_render = false
    }

    if(oldValue && oldValue.value !== newValue.value && !this.first_render){
      if(!newValue.labelKey){
        this.init_value = newValue.value;
        this.init_origin_value = newValue.value
        this.inner_value = newValue.value
      }else{
        if(!newValue.multiple && !newValue.cascader){
          this.init_value = newValue[newValue.labelKey as keyof fieldProps];
          this.init_origin_value = newValue["value"];
          this.inner_value = newValue[newValue.labelKey as keyof fieldProps];
        }else{
          this.init_value = newValue[newValue.labelKey as keyof fieldProps];
          this.init_origin_value = newValue["value"];
          this.inner_value = newValue.value
        }
      }
    }
  }


  // @Watch("value")
  // valueChange(newValue: string, oldValue: string) {
  //   if(oldValue !== newValue && this.first_render) {
  //     console.log(23555)
  //     this.init_value = newValue;
  //   }
  //   if(!this.first_render && oldValue !== newValue) {
  //     this.first_render = true;
  //   }
  // }
  setCaretToEnd() {
    const editableDiv = this.$refs[`editableDiv`] as HTMLElement;
    if (editableDiv) {
      const element = editableDiv;
      const range = document.createRange();
      const selection = window.getSelection();
      range.selectNodeContents(element);
      range.collapse(false);
      selection?.removeAllRanges();
      selection?.addRange(range);
    }
  }
  handleFocus(e:FocusEvent){
    console.log(e)
  }
  handleBlur(e:Event){
    console.log(e)
  }
  handleChange(e: InputEvent){
    const target = e.target as HTMLElement;
    if(target.innerText !== this.init_value){
      this.is_changed = true
    }else{
      this.is_changed = false
    }
  }
  save(){
    this.is_showDiff = true
    this.cursorFocus = false
    const ref = this.$refs['editableDiv'] as HTMLElement;
    if(ref){
      this.first_render = false
      this.handleInput(ref['innerText'])
    }
    if(this.item.labelKey){
      this.handleInput(this.inner_value)
    }
    this.handleSaveClick(this.item)
  }
  revert(){
    this.is_showDiff = false
    this.is_changed = false
    this.first_render = false
    this.handleInput(this.init_origin_value)
    this.inner_editable = false
    this.cursorFocus = false
    this.disableMouseEnter = false
  }
  handleRenderChange(value: string | LicenseEntity[]){
    console.log(value, this.init_value, this.first_render)
      if(!this.item.multiple){
        if(value !== this.init_value && (this.init_value || !this.init_value) && !this.first_render){
          this.is_changed = true
          this.labelValue = value as string
        }else{
          this.is_changed = false
        }
      }else{
        // 判断不等
        if(JSON.stringify((value as LicenseEntity[]).map(j=>j.licenseStandardCode)) !== JSON.stringify((this.init_origin_value as LicenseEntity[]).map(i =>i.licenseStandardCode))){
          let flag:boolean = true;
          (value as LicenseEntity[]).forEach((j) => {
            //@ts-ignore
            if(!(this.init_origin_value as LicenseEntity[]).find(item => item.licenseStandardCode === j.licenseStandardCode)){
              flag = false
            }
          })
          if(!flag || value.length!==this.init_origin_value.length){
            this.is_changed = true
          }
          this.labelValue = (value as LicenseEntity[]).map(j => j.licenseCode).join(",")
        }
      }
  }
  handleEnter(e:KeyboardEvent){
    if(this.disableMouseEnter) return;
    if(this.cursorFocus) return;
    if(this.editable){
      this.showEdit = true
    }
  }
  handleEdit(){
    this.disableMouseEnter = true
    this.inner_editable=true;
    this.showEdit=false
    if(this.render){
      //@ts-ignore
      this.$refs.customComp.focus();

      setTimeout(()=>{
        //@ts-ignore
        this.$refs.customComp.focus();
      }, 100)
    }else{
      this.$nextTick(()=>{
        //@ts-ignore
        this.$refs.editableDiv.click();
        // 手动触发聚焦，使光标显示在 div 中
        //@ts-ignore
        this.$refs.editableDiv.focus();

        // 将光标设置到 div 的末尾（可选）
        const range = document.createRange();
        //@ts-ignore
        range.selectNodeContents(this.$refs.editableDiv);
        range.collapse(false); // 光标定位到内容的末尾
        const selection = window.getSelection();
        if(selection){
          selection.removeAllRanges();
          selection.addRange(range);
        }
      })

    }
    this.cursorFocus = true
    setTimeout(()=>{
      this.disableMouseEnter = false
    }, 200)
  }
}
</script>

<template>
  <div style="display: flex;flex:1" @mouseenter="handleEnter" @mouseleave="()=>{showEdit=false;}">
    <template v-if="!render">
      <template v-if="!inner_editable">
        <div :title="inner_value" :style="{maxWidth: maxWidth+'px',textOverflow: 'ellipsis',overflow: 'hidden',whiteSpace: 'nowrap', cursor: 'pointer'}" class="cc-edit-input-wrapper">
          {{inner_value}}
        </div>
      </template>
      <template v-else>
        <div class="cc-edit-input-wrapper"
             :style="{width: `${maxWidth}px`}"
             :contenteditable="inner_editable && injectedModeType.mode != 'preview'"
             @focus="handleFocus"
             @blur="handleBlur"
             @input="handleChange"
             tabindex="0"
             :ref="`editableDiv`"
             v-if="!is_showDiff"
        >{{inner_value}}</div>
      </template>
    </template>
    <template v-else>
      <Component :is="render" v-model="inner_value" :item="item" @change="handleRenderChange" v-show="!is_showDiff" :editable="inner_editable && injectedModeType.mode != 'preview'" ref="customComp"></Component>
    </template>

    <div v-if="is_changed && !is_showDiff && injectedModeType.mode != 'preview' && editable" style="color: #409EFF;cursor: pointer;font-size: 12px;min-height:28px;line-height: 28px" @click="save">
      保存
    </div>
    <div style="color: #409EFF;cursor: pointer;font-size: 12px;min-height:28px;line-height: 28px;padding-left:10px;" v-if="showEdit && !is_changed && injectedModeType.mode != 'preview'" @click.stop="handleEdit">
      修改
    </div>
    <div v-if="is_showDiff">
      <div style="display: flex;align-items: center;min-height:28px;line-height: 28px;padding-top:3px;">
        <div style="font-size: 12px">修改后：</div>
        <div :style="{marginLeft: '5px',lineHeight: '100%', display: 'flex',flexDirection: 'column', width: `${maxWidth - 90}px`}">
          <template v-if="item.labelKey">
            <template v-if="!item.multiple">
              <div :style="{maxWidth: `${maxWidth-20}px`, textOverflow: 'ellipsis',overflow: 'hidden',whiteSpace: 'nowrap'}" :title="labelValue">
                {{ labelValue }}
              </div>
            </template>
            <template v-else>
              <div class="registrationLis">
                <div v-for="(i,index) in inner_value" :key="index" :style="{maxWidth: `${maxWidth-20}px`, textOverflow: 'ellipsis',overflow: 'hidden',whiteSpace: 'nowrap'}"  :title="i[item.labelKey]">
                  {{i[item.labelKey]}}
                </div>
              </div>
            </template>
          </template>
          <template v-else>
            <div :style="{maxWidth: `${maxWidth-20}px`, textOverflow: 'ellipsis',overflow: 'hidden',whiteSpace: 'nowrap'}"  :title="value">
              {{ value }}
            </div>
          </template>
        </div>
        <div v-if="injectedModeType.mode != 'preview'" style="margin-left: 15px;color: #409EFF;cursor: pointer;font-size: 12px;" @click="revert">撤销</div>
      </div>
      <div style="display: flex;align-items: center;min-height:28px;line-height: 28px">
        <div style="font-size: 12px">修改前：</div>
        <div style="margin-left: 5px;line-height: 100%;display: flex;flex-direction: column">
          <template v-if="item.labelKey">
            <template v-if="!item.multiple">
              <div :style="{maxWidth: `${maxWidth-20}px`, textOverflow: 'ellipsis',overflow: 'hidden',whiteSpace: 'nowrap'}"  :title="init_value">
                {{ init_value }}
              </div>
            </template>
            <template v-else>
              <div>
                <div v-for="(i,index) in init_origin_value" :key="index" :style="{maxWidth: `${maxWidth-20}px`, textOverflow: 'ellipsis',overflow: 'hidden',whiteSpace: 'nowrap', marginTop: '5px'}"  :title="i[item.labelKey]">
                  {{i[item.labelKey]}}
                </div>
              </div>
            </template>
          </template>
          <template v-else>
            <div :style="{maxWidth: `${maxWidth-20}px`, textOverflow: 'ellipsis',overflow: 'hidden',whiteSpace: 'nowrap'}"  :title="init_value">
              {{init_value}}
            </div>
          </template>
        </div>
      </div>
    </div>
  </div>

</template>

<style scoped lang="scss">
.cc-edit-input-wrapper{
  height: 28px;
  line-height: 28px;
  white-space: nowrap;
  overflow: hidden;
}
.cc-edit-input-wrapper:focus-within{
  border: none;
  outline: none;
}
.registrationLis{
  :has(div){
    padding-top:3px;
  }
  div:nth-child(n+2){
    margin-top: 5px;
  }
}
</style>